<script setup lang="ts">
import { ref, getCurrentInstance } from 'vue'
import { ElMessage } from 'element-plus'
import { defaultMapStore } from '@/store'
import { fromLonLat } from 'ol/proj'
import GeoJSON from 'ol/format/GeoJSON'
import { Style, Stroke } from 'ol/style'
import { Layer, Vector as VectorLayer } from 'ol/layer'
import { Vector as VectorSource } from 'ol/source'
import Feature from 'ol/Feature'
import { Geometry } from 'ol/geom'

const prefix = import.meta.env.VITE_BASE_URL
const searchedArea = ref('')
const displayArea = ref(false)
let cityData = ref([]), cityDataCopy
let cityList
const area = ref('温州市')
const { proxy }: any = getCurrentInstance()
const customNodeClass = (data: any) => {
  if (data.fatherNode) {
    return 'is-father'
  }
  return null
}

proxy.axios.get(prefix + '/static/data/cityList.json').then((res: any) => {
  cityList = res.data
})

proxy.axios.get(prefix + '/static/data/cityData.json').then((res: any) => {
  cityDataCopy = res.data
  cityData.value = res.data
})
const searchArea = (area: String) => {
  cityData.value = cityDataCopy
  if (area && cityData.value) {
    let data: Set<Object> = new Set()
    cityData.value.forEach((city: any) => {
      if (city.label.includes(area)) {
        data.add(city)
      }
      city.children.forEach((child: any) => {
        if (child.label.includes(area)) {
          city.children = city.children.filter((a: any) => a.label.includes(area))
          data.add(city)
        }
      })
    })
    if (data.size === 0) {
      ElMessage({
        message: '你输入的地点不存在，请重新输入',
        type: 'warning'
      })
    }
    cityData.value = Array.from(data)
  } else {
    ElMessage({
      message: '请输入你想要查找的地点',
      type: 'warning'
    })
  }
}

const toggleArea = (item: any) => {
  const map = defaultMapStore().getMap()
  const anchor = defaultMapStore().getAnchor()
  map.getAllLayers().forEach((layer: Layer) => {
    if (layer instanceof VectorLayer && layer.get('name') === '地区图层') {
      map.removeLayer(layer)
      defaultMapStore().setMap(map)
    }
  })
  const geojson = new GeoJSON()
  proxy.axios.get(item.geojsonAddress).then((res: any) => {
    const features: Feature<Geometry>[] = geojson.readFeatures(res.data) as Feature<Geometry>[]
    const geometry = features[0].getGeometry()!
    geometry.transform('EPSG:4326', 'EPSG:3857')
    const source: VectorSource<Feature<Geometry>> = new VectorSource({
      features
    })
    const layer = new VectorLayer({
      source,
      style: new Style({
        stroke: new Stroke({
          color: 'blue',
          width: 3,
        }),
      }),
      properties: {
        name: '地区图层'
      }
    })
    map.addLayer(layer)
    anchor.setPosition(fromLonLat(item.center))
    area.value = item.label
    map.getView().fit(features[0].getGeometry(), {
      maxZoom: map.getView().getZoom(),
      duration: 200
    })
    defaultMapStore().setToggleCenter(fromLonLat(item.center))
  })
}
</script>

<template>
  <view class="choosecity">
    <el-input placeholder="请输入地区名称" @click.prevent="displayArea = true" v-model="searchedArea">
      <template #prepend>
        <view @click="displayArea = true">
          <view class="iconfont">&#xe617;</view>
          <p class="city">{{ area }}</p>
        </view>
      </template>
      <template #append>
        <view class="search" @click="searchArea(searchedArea)">
          <view class="iconfont">&#xe685;</view>
        </view>
      </template>
    </el-input>
    <view class="exp" v-show="displayArea">
      <view class="m-dialog">
        <view class="u-diatitle">
          <text>当前地区:{{ area }}</text>
          <img v-lazy="prefix + '/images/close.png'" class="u-closebtn" @click="displayArea = false">
        </view>
        <view class="u-hotcity">
          <view class="title">常用地区</view>
          <view class="cityList">
            <view class="city" v-for="(item, index) in cityList" :key="index" @click="toggleArea(item)">{{ item.label }}
            </view>
          </view>
        </view>
        <view class="u-bechocity">地区列表</view>
        <view class="m-citylist">
          <el-tree :data="cityData" :props="{ class: customNodeClass }" accordion @node-click="toggleArea" />
        </view>
      </view>
    </view>
  </view>
</template>

<style lang="scss">
@import '@/assets/mixin.scss';
$bg-color: #f2f8ff;
$font-color: #4b78d0;

.choosecity {
  @include positionTopLeft(absolute, 0.3rem, 0.3rem);
  width: 79%;
  z-index: 999;

  .el-input {
    height: 1.333rem;
    box-shadow: 0 0 0.42667rem 0 rgba(1, 0, 20, .4);
    border-radius: 0.1rem;

    .el-input-group__prepend {
      background-color: #e6f2ff;
      border-radius: 0.1rem 0 0 0.1rem;
      cursor: pointer;

      view {
        display: flex;

        view.iconfont {
          font-size: 0.4rem;
          color: #0079FF;
          margin-right: 0.1rem;
          margin-left: -0.2rem;
          vertical-align: bottom;
        }

        .city {
          font-size: 0.4rem;
          color: #0079FF;
          margin-right: -0.2rem;
          margin-top: 0.05rem;
        }
      }
    }

    .el-input__wrapper {
      font-size: 0.4rem;
      padding-left: 0.3rem;
    }

    .el-input__wrapper.is-focus {
      box-shadow: none !important;
    }

    .el-input-group__append {
      background-color: #e6f2ff;
      border-radius: 0 0.1rem 0.1rem 0;
      cursor: pointer;

      .search {
        view.iconfont {
          font-size: 0.4rem;
          color: #0079FF;
        }
      }

      // 点击按钮后变色
      &:active {
        background-color: #ccc;
      }
    }
  }

  .exp {
    @include positionTopLeft(absolute, 1.45rem);
    box-shadow: 0 0 .1rem rgba(0, 0, 0, .5);
    border-radius: 1%;
    background: #fff;
    font-size: 0.48rem;
    color: #838383;

    .m-dialog {
      width: 10rem;
      height: 13rem;
      padding: 0.33333rem;

      .u-diatitle {
        @include flex(space-between, center);
        border-bottom: 1px solid #e4e4e4;
        padding: 0 0.2rem 0.3rem;

        text {
          font-size: 0.52rem;
        }

        .u-closebtn {
          transform: scale(1.1);
          cursor: pointer;
        }
      }

      .u-hotcity {
        line-height: 0.5rem;
        padding: 0.3rem 0;

        .title {
          padding-bottom: 0.3rem;
        }

        .cityList {
          @include grid(repeat(4, 1fr), repeat(4, 1fr));
          background-color: $bg-color;

          .city {
            @include flex(center, center);
            height: 1.2rem;
            color: $font-color;
            cursor: pointer;
          }
        }
      }

      .u-bechocity {
        margin-bottom: 0.3rem;
      }

      .m-citylist {
        height: 3.941rem;
        overflow: auto;
        background-color: $bg-color;

        .is-father {
          background-color: $bg-color;
          color: $font-color;
          font-weight: bold;
          font-size: 0.45rem;
          padding: 0.2rem 0;

          &:first-child {
            padding-top: 0.05rem;
          }

          &>.el-tree-node__content {
            .el-tree-node__expand-icon {
              font-size: 0.45rem;
              color: $font-color;
              opacity: .55;
            }

            .el-tree-node__label {
              margin-left: 0.3rem;
            }
          }

          &>.el-tree-node__children {
            width: 90%;
            margin: 0 auto;
            @include grid(repeat(4, 1fr), auto);
            color: $font-color;
            font-weight: normal;
            font-size: 0.45rem;

            .el-tree-node {
              margin-top: 0.68rem;
              text-align: center;

              .el-tree-node__content>i {
                display: none;
              }
            }
          }
        }
      }
    }
  }
}

@media screen and (max-width: 540px) {
  .choosecity {
    .exp {
      .m-dialog {
        width: 8rem;
        height: 13rem;
        padding: 0.33333rem;
      }
    }
  }
}
</style>
